IDENTIFICATION DIVISION.
PROGRAM-ID. FACECAT.

DATA DIVISIONDIVISION.
WORKING-STORAGE SECTION.
01 FCPoint.
    05 X PIC S9(9)V9(2) VALUE 0.  * 横坐标
    05 Y PIC S9(9)V9(2) VALUE 0.  * 纵坐标

PROCEDURE DIVISION.
INITIALIZE-POINT.
    ACCEPT IX.
    ACCEPT IY.
    MOVE IX TO X.
    MOVE IY TO Y.
    EXIT PROGRAM.

IDENTIFICATION DIVISION.
PROGRAM-ID. FCSizeClass.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 FCSize.
    05 CX PIC S9(9)V9(2) VALUE 0.  * 长
    05 CY PIC S9(9)V9(2) VALUE 0.  * 宽

PROCEDURE DIVISION.
INITIALIZE-SIZE.
    ACCEPT ICX.
    ACCEPT ICY.
    MOVE ICX TO CX.
    MOVE ICY TO CY.
    EXIT PROGRAM.

IDENTIFICATION DIVISION.
PROGRAM-ID. FCRectClass.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 FCRect.
    05 LEFT PIC S9(9)V9(2) VALUE 0.
    05 TOP PIC S9(9)V9(2) VALUE 0.
    05 RIGHT PIC S9(9)V9(2) VALUE 0.
    05 BOTTOM PIC S9(9)V9(2) VALUE 0.

PROCEDURE DIVISION.
INITIALIZE-RECT.
    ACCEPT ILEFT.
    ACCEPT ITOP.
    ACCEPT IRIGHT.
    ACCEPT IBOTTOM.
    MOVE ILEFT TO LEFT.
    MOVE ITOP TO TOP.
    MOVE IRIGHT TO RIGHT.
    MOVE IBOTTOM TO BOTTOM.
    EXIT PROGRAM.

IDENTIFICATION DIVISION.
PROGRAM-ID. FCPaddingClass.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 FCPadding.
    05 LEFT PIC S9(9)V9(2) VALUE 0.
    05 TOP PIC S9(9)V9(2) VALUE 0.
    05 RIGHT PIC S9(9)V9(2) VALUE 0.
    05 BOTTOM PIC S9(9)V9(2) VALUE 0.

PROCEDURE DIVISION.
INITIALIZE-PADDING.
    ACCEPT ILEFT.
    ACCEPT ITOP.
    ACCEPT IRIGHT.
    ACCEPT IBOTTOM.
    MOVE ILEFT TO LEFT.
    MOVE ITOP TO TOP.
    MOVE IRIGHT TO RIGHT.
    MOVE IBOTTOM TO BOTTOM.
    EXIT PROGRAM.

IDENTIFICATION DIVISION.
PROGRAM-ID. FCPaintClass.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 FCPaint.
    05 CANCEL-CLICK PIC X(1) VALUE "N".  * 是否退出点击
    05 DEFAULT-UI-STYLE PIC X(5) VALUE "light".  * 默认样式
    05 DRAG-BEGIN-POINT.
        10 X PIC S9(9)V9(2) VALUE 0.  * 拖动开始时触摸位置横坐标
        10 Y PIC S9(9)V9(2) VALUE 0.  * 拖动开始时触摸位置纵坐标
    05 DRAG-BEGIN-RECT.
        10 LEFT PIC S9(9)V9(2) VALUE 0.
        10 TOP PIC S9(9)V9(2) VALUE 0.
        10 RIGHT PIC S9(9)V9(2) VALUE 0.
        10 BOTTOM PIC S9(9)V9(2) VALUE 0.
    05 DRAGGING-VIEW.
        10 VIEW-ID PIC 9(5).  * 视图
        10 FILLER PIC X(45).  
    05 EDITING-TEXT-BOX.
        10 VIEW-ID PIC 9(5).  * 正在编辑的文本框视图
        10 FILLER PIC X(45).
    05 FIRST-TOUCH PIC X(1) VALUE "N".
    05 FOCUSED-VIEW.
        10 VIEW-ID PIC 9(5).  * 焦点视图ID
        10 FILLER PIC X(45).
    05 IS-DOUBLE-CLICK PIC X(1) VALUE "N".
    05 IS-MOBILE PIC X(1) VALUE "N".
    05 IS-PATH PIC X(1) VALUE "N".
    05 LAST-CLICK-TIME PIC 9(9)V9(2) VALUE 0.  * 上次点击时间
    05 MOVE-TO PIC X(1) VALUE "N".
    05 OFFSET-X PIC S9(9)V9(2) VALUE 0.  * 横向偏移
    05 OFFSET-Y PIC S9(9)V9(2) VALUE 0.  * 纵向偏移
    05 RATIO PIC S9(9)V9(2) VALUE 1.  * 缩放比例
    05 RESIZE-COLUMN-STATE PIC S9(9)V9(2) VALUE 0.
    05 RESIZE-COLUMN-BEGIN-WIDTH PIC S9(9)V9(2) VALUE 0.
    05 RESIZE-COLUMN-INDEX PIC 9(1) VALUE -1.
    05 SCALE-FACTOR-X PIC S9(9)V9(2) VALUE 1.
    05 SCALE-FACTOR-Y PIC S9(9)V9(2) VALUE 1.
    05 SECOND-TOUCH PIC X(1) VALUE "N".
    05 SYSTEM-FONT PIC X(10) VALUE "Arial".  * 系统字体
    05 TOUCH-DOWN-POINT.
        10 X PIC S9(9)V9(2) VALUE 0.
        10 Y PIC S9(9)V9(2) VALUE 0.
    05 TOUCH-FIRST-POINT.
        10 X PIC S9(9)V9(2) VALUE 0.
        10 Y PIC S9(9)V9(2) VALUE 0.
    05 TOUCH-SECOND-POINT.
        10 X PIC S9(9)V9(2) VALUE 0.
        10 Y PIC S9(9)V9(2) VALUE 0.
    05 TOUCH-DOWN-VIEW.
        10 VIEW-ID PIC 9(5).  * 鼠标按下的视图
        10 FILLER PIC X(45).
    05 TOUCH-MOVE-VIEW.
        10 VIEW-ID PIC 9(5).  * 鼠标移动的视图
        10 FILLER PIC X(45).
    05 VIEWS OCCURS 0 TO 100 TIMES DEPENDING ON VIEW-COUNT.  
        10 VIEW-ID PIC 9(5).  * 视图集合
        10 FILLER PIC X(45).

PROCEDURE DIVISION.

* 添加线
ADD-LINE.
    ACCEPT X1.
    ACCEPT Y1.
    ACCEPT X2.
    ACCEPT Y2.
    EXIT PROGRAM.

* 开始路径
BEGIN-PATH.
    EXIT PROGRAM.

* 开始绘图
BEGIN-PAINT.
    ACCEPT RECT-LEFT.
    ACCEPT RECT-TOP.
    ACCEPT RECT-RIGHT.
    ACCEPT RECT-BOTTOM.
    EXIT PROGRAM.

* 闭合路径
CLOSE-FIGURE.
    EXIT PROGRAM.

* 关闭路径
CLOSE-PATH.
    EXIT PROGRAM.

* 绘制线
DRAW-LINE.
    ACCEPT COLOR.
    ACCEPT WIDTH.
    ACCEPT STYLE OCCURS 0 TO 10 TIMES DEPENDING ON STYLE-COUNT.  
    ACCEPT X1.
    ACCEPT Y1.
    ACCEPT X2.
    ACCEPT Y2.
    EXIT PROGRAM.

* 绘制路径
DRAW-PATH.
    ACCEPT COLOR.
    ACCEPT WIDTH.
    ACCEPT STYLE OCCURS 0 TO 10 TIMES DEPENDING ON STYLE-COUNT.
    EXIT PROGRAM.

* 绘制连续线条
DRAW-POLYLINE.
    ACCEPT COLOR.
    ACCEPT WIDTH.
    ACCEPT STYLE OCCURS 0 TO 10 TIMES DEPENDING ON STYLE-COUNT.
    ACCEPT APT OCCURS 0 TO 100 TIMES DEPENDING ON APT-COUNT.  
        10 X PIC S9(9)V9(2).
        10 Y PIC S9(9)V9(2).
    EXIT PROGRAM.

* 绘制多边形
DRAW-POLYGON.
    ACCEPT COLOR.
    ACCEPT WIDTH.
    ACCEPT STYLE OCCURS 0 TO 10 TIMES DEPENDING ON STYLE-COUNT.
    ACCEPT APT OCCURS 0 TO 100 TIMES DEPENDING ON APT-COUNT.
        10 X PIC S9(9)V9(2).
        10 Y PIC S9(9)V9(2).
    EXIT PROGRAM.

* 绘制图片
DRAW-IMAGE.
    ACCEPT IMAGE-ID.  
    ACCEPT LEFT.
    ACCEPT TOP.
    ACCEPT RIGHT.
    ACCEPT BOTTOM.
    EXIT PROGRAM.

* 绘制矩形
DRAW-RECT.
    ACCEPT COLOR.
    ACCEPT WIDTH.
    ACCEPT STYLE OCCURS 0 TO 10 TIMES DEPENDING ON STYLE-COUNT.
    ACCEPT LEFT.
    ACCEPT TOP.
    ACCEPT RIGHT.
    ACCEPT BOTTOM.
    EXIT PROGRAM.

* 绘制椭圆
DRAW-ELLIPSE.
    ACCEPT COLOR.
    ACCEPT WIDTH.
    ACCEPT STYLE OCCURS 0 TO 10 TIMES DEPENDING ON STYLE-COUNT.
    ACCEPT LEFT.
    ACCEPT TOP.
    ACCEPT RIGHT.
    ACCEPT BOTTOM.
    EXIT PROGRAM.

* 绘制圆角矩形
DRAW-ROUND-RECT.
    ACCEPT COLOR.
    ACCEPT WIDTH.
    ACCEPT STYLE OCCURS 0 TO 10 TIMES DEPENDING ON STYLE-COUNT.
    ACCEPT LEFT.
    ACCEPT TOP.
    ACCEPT RIGHT.
    ACCEPT BOTTOM.
    ACCEPT CORNER-RADIUS.
    EXIT PROGRAM.

* 绘制文字
DRAW-TEXT.
    ACCEPT TEXT.
    ACCEPT COLOR.
    ACCEPT FONT.
    ACCEPT X.
    ACCEPT Y.
    EXIT PROGRAM.

* 结束绘图
END-PAINT.
    EXIT PROGRAM.

* 填充路径
FILL-PATH.
    ACCEPT COLOR.
    EXIT PROGRAM.

* 填充多边形
FILL-POLYGON.
    ACCEPT COLOR.
    ACCEPT APT OCCURS 0 TO 100 TIMES DEPENDING ON APT-COUNT.
        10 X PIC S9(9)V9(2).
        10 Y PIC S9(9)V9(2).
    EXIT PROGRAM.

* 填充矩形
FILL-RECT.
    ACCEPT COLOR.
    ACCEPT LEFT.
    ACCEPT TOP.
    ACCEPT RIGHT.
    ACCEPT BOTTOM.
    EXIT PROGRAM.

* 填充圆角矩形
FILL-ROUND-RECT.
    ACCEPT COLOR.
    ACCEPT LEFT.
    ACCEPT TOP.
    ACCEPT RIGHT.
    ACCEPT BOTTOM.
    ACCEPT CORNER-RADIUS.
    EXIT PROGRAM.

* 填充椭圆
FILL-ELLIPSE.
    ACCEPT COLOR.
    ACCEPT LEFT.
    ACCEPT TOP.
    ACCEPT RIGHT.
    ACCEPT BOTTOM.
    EXIT PROGRAM.

* 裁剪
SET-CLIP.
    ACCEPT LEFT.
    ACCEPT TOP.
    ACCEPT RIGHT.
    ACCEPT BOTTOM.
    EXIT PROGRAM.

* 设置偏移量
SET-OFFSET.
    ACCEPT X.
    ACCEPT Y.
    MOVE X TO OFFSET-X.
    MOVE Y TO OFFSET-Y.
    EXIT PROGRAM.

* 获取字体大小
TEXT-SIZE PROCEDURE.
    DISPLAY 
    MOVE 0 TO RETURN-SIZE.CX.
    MOVE 0 TO RETURN-SIZE.CY.
    EXIT PROGRAM.
    05 RETURN-SIZE.
        10 CX              PIC S9(9)V9(2).
        10 CY              PIC S9(9)V9(2).

* 保存状态
SAVE PROCEDURE.
    DISPLAY 
    EXIT PROGRAM.

* 恢复状态
RESTORE PROCEDURE.
    DISPLAY 
    EXIT PROGRAM.

* 绘制文字自动省略
DRAW-TEXT-AUTO-ELLIPSIS PROCEDURE.
    DISPLAY 
    ACCEPT TEXT.
    ACCEPT COLOR.
    ACCEPT FONT.
    ACCEPT LEFT.
    ACCEPT TOP.
    ACCEPT RIGHT.
    ACCEPT BOTTOM.
    IF TEXT IS NOT SPACE AND LENGTH OF TEXT > 0
        PERFORM VARYING I FROM 1 BY 1 UNTIL I > LENGTH OF TEXT
            IF TEXT (I:I) = SPACE
                MOVE I TO SPACE-POSITION
            END-IF
        END-PERFORM
        PERFORM GET-FONT-SIZE USING TEXT FONT RETURNING T-SIZE
        IF T-SIZE.CX < RIGHT - LEFT
            PERFORM DRAW-TEXT USING TEXT COLOR FONT LEFT TOP
        ELSE
            IF T-SIZE.CX > 0
                MOVE 3 TO SUB-LEN
                PERFORM VARYING NEW-LEN FROM LENGTH OF TEXT - SUB-LEN BY 1 UNTIL NEW-LEN <= 0
                    MOVE TEXT (1:NEW-LEN) CONCAT "..." TO NEW-TEXT
                    PERFORM GET-FONT-SIZE USING NEW-TEXT FONT RETURNING T-SIZE
                    IF T-SIZE.CX < RIGHT - LEFT
                        PERFORM DRAW-TEXT USING NEW-TEXT COLOR FONT LEFT TOP

IDENTIFICATION DIVISION.
PROGRAM-ID. FCViewClass.

DATA DIVISION.
WORKING-STORAGE SECTION.

01 FCView.
    05 ALLOW-DRAG            PIC X(1)     VALUE "N".    * 是否允许拖动
    05 ALLOW-RESIZE          PIC X(1)     VALUE "N".
    05 ALIGN                  PIC X(10)    VALUE "left". * 横向布局
    05 ALLOW-DRAG-SCROLL      PIC X(1)     VALUE "Y".
    05 ALLOW-PREVIEWS-EVENT  PIC X(1)     VALUE "N".
    05 BACK-COLOR             PIC X(15)    VALUE "rgb(255,255,255)". * 背景色
    05 BORDER-COLOR           PIC X(15)    VALUE "rgb(150,150,150)".
    05 BORDER-WIDTH           PIC 9(3)V9(2)  VALUE 1.    * 边线宽度
    05 CLIP-RECT.
        10 LEFT              PIC S9(9)V9(2)  VALUE 0.
        10 TOP               PIC S9(9)V9(2)  VALUE 0.
        10 RIGHT             PIC S9(9)V9(2)  VALUE 0.
        10 BOTTOM            PIC S9(9)V9(2)  VALUE 0.
    05 CORNER-RADIUS          PIC S9(9)V9(2)  VALUE 0.
    05 CURSOR                 PIC X(20)    VALUE SPACES. * 光标
    05 DOWN-SCROLL-H-BUTTON   PIC X(1)     VALUE "N".
    05 DOWN-SCROLL-V-BUTTON   PIC X(1)     VALUE "N".
    05 DISPLAY-OFFSET         PIC X(1)     VALUE "Y".
    05 DOCK                   PIC X(10)    VALUE "none".
    05 ENABLED                PIC X(1)     VALUE "Y".
    05 EX-ATTRIBUTES.
        10 ATTRIBUTE-COUNT   PIC 9(3).    
        10 ATTRIBUTE-ENTRIES OCCURS 0 TO 100 TIMES DEPENDING ON ATTRIBUTE-COUNT.  
            15 KEY            PIC X(50).  
            15 VALUE          PIC X(50).
    05 FONT                   PIC X(20)    VALUE "Default,12".
    05 HOVERED-COLOR          PIC X(15)    VALUE SPACES. * 鼠标悬停时颜色
    05 HOVER-SCROLL-H-BUTTON  PIC X(1)     VALUE "N".
    05 HOVER-SCROLL-V-BUTTON  PIC X(1)     VALUE "N".
    05 H-SCROLL-IS-VISIBLE    PIC X(1)     VALUE "N".
    05 LOCATION.
        10 X                 PIC S9(9)V9(2)  VALUE 0.
        10 Y                 PIC S9(9)V9(2)  VALUE 0.
    05 MARGIN.
        10 LEFT              PIC S9(9)V9(2)  VALUE 0.
        10 TOP               PIC S9(9)V9(2)  VALUE 0.
        10 RIGHT             PIC S9(9)V9(2)  VALUE 0.
        10 BOTTOM            PIC S9(9)V9(2)  VALUE 0.
    05 MAXIMUM-SIZE.
        10 CX                PIC S9(9)V9(2)  VALUE 0.
        10 CY                PIC S9(9)V9(2)  VALUE 0.
    05 PADDING.
        10 LEFT              PIC S9(9)V9(2)  VALUE 0.
        10 TOP               PIC S9(9)V9(2)  VALUE 0.
        10 RIGHT             PIC S9(9)V9(2)  VALUE 0.
        10 BOTTOM            PIC S9(9)V9(2)  VALUE 0.
    05 PAINT.
        10 PAINT-RECORD.
            15 PAINT-ID        PIC 9(5).    
            15 FILLER         PIC X(45).   
    05 PARENT.
        10 PARENT-RECORD.
            15 PARENT-ID        PIC 9(5).
            15 FILLER         PIC X(45).
    05 PUSHED-COLOR           PIC X(15)    VALUE "rgb(100,100,100)".
    05 RESIZE-POINT           PIC S9(9)V9(2)  VALUE -1.
    05 SCROLL-V               PIC S9(9)V9(2)  VALUE 0.
    05 SCROLL-H               PIC S9(9)V9(2)  VALUE 0.
    05 SCROLL-SIZE            PIC S9(9)V9(2)  VALUE 8.
    05 SHOW-H-SCROLL-BAR      PIC X(1)     VALUE "N".
    05 SHOW-V-SCROLL-BAR      PIC X(1)     VALUE "N".
    05 SCROLL-BAR-COLOR       PIC X(15)    VALUE "rgb(200,200,200)".
    05 SCROLL-BAR-HOVERED-COLOR PIC X(15)    VALUE "rgb(42,138,195)".
    05 SIZE.
        10 CX                PIC S9(9)V9(2)  VALUE 0.
        10 CY                PIC S9(9)V9(2)  VALUE 0.
    05 START-SCROLL-H         PIC S9(9)V9(2)  VALUE 0.
    05 START-SCROLL-V         PIC S9(9)V9(2)  VALUE 0.
    05 START-POINT.
        10 X                 PIC S9(9)V9(2)  VALUE 0.
        10 Y                 PIC S9(9)V9(2)  VALUE 0.
    05 START-RECT.
        10 LEFT              PIC S9(9)V9(2)  VALUE 0.
        10 TOP               PIC S9(9)V9(2)  VALUE 0.
        10 RIGHT             PIC S9(9)V9(2)  VALUE 0.
        10 BOTTOM            PIC S9(9)V9(2)  VALUE 0.
    05 TAB-INDEX              PIC 9(3)     VALUE 0.    * Tab索引
    05 TAB-STOP               PIC X(1)     VALUE "N".
    05 TEXT                   PIC X(100)   VALUE SPACES. * 文字内容
    05 TEXT-COLOR             PIC X(15)    VALUE "rgb(0,0,0)".
    05 TEXT-ALIGN             PIC X(10)    VALUE "left".
    05 TOP-MOST               PIC X(1)     VALUE "N".
    05 TOUCH-DOWN-TIME        PIC 9(9)V9(2)  VALUE 0.
    05 VIEW-NAME              PIC X(50)    VALUE SPACES. * 视图名称
    05 VISIBLE                PIC X(1)     VALUE "Y".
    05 VERTICAL-ALIGN         PIC X(10)    VALUE "top".
    05 VIEW-TYPE              PIC X(10)    VALUE "none".
    05 V-SCROLL-IS-VISIBLE    PIC X(1)     VALUE "N".
    05 VIEWS OCCURS 0 TO 100 TIMES DEPENDING ON VIEWS-COUNT. 
        10 VIEW-RECORD.
            15 VIEW-ID        PIC 9(5).
            15 FILLER         PIC X(45).

INITIALIZE-FCView PROCEDURE.
    MOVE "N" TO FCView.ALLOW-DRAG
    MOVE "N" TO FCView.ALLOW-RESIZE
    MOVE 1 TO FCView.BORDER-WIDTH
    MOVE 0 TO FCView.CLIP-RECT.LEFT
    MOVE 0 TO FCView.CLIP-RECT.TOP
    MOVE 0 TO FCView.CLIP-RECT.RIGHT
    MOVE 0 TO FCView.CLIP-RECT.BOTTOM
    MOVE 0 TO FCView.CORNER-RADIUS
    MOVE "N" TO FCView.DOWN-SCROLL-H-BUTTON
    MOVE "N" TO FCView.DOWN-SCROLL-V-BUTTON
    MOVE "Y" TO FCView.DISPLAY-OFFSET
    MOVE "Y" TO FCView.ENABLED
    MOVE 0 TO FCView.EX-ATTRIBUTES.ATTRIBUTE-COUNT
    PERFORM VARYING I FROM 1 BY 1 UNTIL I > 100
        MOVE SPACES TO FCView.EX-ATTRIBUTES.ATTRIBUTE-ENTRIES (I).KEY
        MOVE SPACES TO FCView.EX-ATTRIBUTES.ATTRIBUTE-ENTRIES (I).VALUE
    END-PERFORM
    MOVE "N" TO FCView.HOVER-SCROLL-H-BUTTON
    MOVE "N" TO FCView.HOVER-SCROLL-V-BUTTON
    MOVE "N" TO FCView.H-SCROLL-IS-VISIBLE
    MOVE 0 TO FCView.LOCATION.X
    MOVE 0 TO FCView.LOCATION.Y
    MOVE 0 TO FCView.MARGIN.LEFT
    MOVE 0 TO FCView.MARGIN.TOP
    MOVE 0 TO FCView.MARGIN.RIGHT
    MOVE 0 TO FCView.MARGIN.BOTTOM
    MOVE 0 TO FCView.MAXIMUM-SIZE.CX
    MOVE 0 TO FCView.MAXIMUM-SIZE.CY
    MOVE 0 TO FCView.PADDING.LEFT
    MOVE 0 TO FCView.PADDING.TOP
    MOVE 0 TO FCView.PADDING.RIGHT
    MOVE 0 TO FCView.PADDING.BOTTOM
    MOVE 0 TO FCView.PAINT.PAINT-RECORD.PAINT-ID
    MOVE 0 TO FCView.PARENT.PARENT-RECORD.PARENT-ID
    MOVE -1 TO FCView.RESIZE-POINT
    MOVE 0 TO FCView.SCROLL-V
    MOVE 0 TO FCView.SCROLL-H
    MOVE 8 TO FCView.SCROLL-SIZE
    MOVE "N" TO FCView.SHOW-H-SCROLL-BAR
    MOVE "N" TO FCView.SHOW-V-SCROLL-BAR
    MOVE 0 TO FCView.SIZE.CX
    MOVE 0 TO FCView.SIZE.CY
    MOVE 0 TO FCView.START-SCROLL-H
    MOVE 0 TO FCView.START-SCROLL-V
    MOVE 0 TO FCView.START-POINT.X
    MOVE 0 TO FCView.START-POINT.Y
    MOVE 0 TO FCView.START-RECT.LEFT
    MOVE 0 TO FCView.START-RECT.TOP
    MOVE 0 TO FCView.START-RECT.RIGHT
    MOVE 0 TO FCView.START-RECT.BOTTOM
    MOVE 0 TO FCView.TAB-INDEX
    MOVE "N" TO FCView.TAB-STOP
    MOVE SPACES TO FCView.TEXT
    MOVE "N" TO FCView.V-SCROLL-IS-VISIBLE
    MOVE 0 TO FCView.VIEWS-COUNT
    PERFORM VARYING I FROM 1 BY 1 UNTIL I > 100
        MOVE 0 TO FCView.VIEWS (I).VIEW-RECORD.VIEW-ID
        MOVE SPACES TO FCView.VIEWS (I).VIEW-RECORD.FILLER
    END-PERFORM
    EXIT PROGRAM.

IDENTIFICATION DIVISION.
PROGRAM-ID. ViewFunctions.

DATA DIVISION.
WORKING-STORAGE SECTION.

01 VIEW-COUNT       PIC 9(3).
01 TEMP-VIEW-RECORD.
    05 TEMP-VIEW-ID  PIC 9(5).
    05 FILLER        PIC X(45).

01 TEMP-X           PIC S9(9)V9(2).
01 TEMP-Y           PIC S9(9)V9(2).
01 TEMP-CX          PIC S9(9)V9(2).
01 TEMP-CY          PIC S9(9)V9(2).

01 I                PIC 9(3).
01 J                PIC 9(3).

01 RESULT-BOOLEAN   PIC X(1).

PROCEDURE DIVISION.

* 添加顶层视图
ADD-VIEW PROCEDURE.
    SET VIEW-RECORD-IN-PAINT TO VIEW-ID IN VIEW.
    SET PAINT-ID IN VIEW TO PAINT-ID IN PAINT.
    ADD VIEW TO PAINT-VIEWS.
    EXIT PROGRAM.
    ADD VIEW TO PAINT-VIEWS.
        DISPLAY 
        MOVE VIEW-RECORD TO TEMP-VIEW-RECORD
        ADD 1 TO VIEW-COUNT
        PERFORM INCREASE-ARRAY-SIZE
        MOVE TEMP-VIEW-RECORD TO PAINT-VIEWS (VIEW-COUNT)
    INCREASE-ARRAY-SIZE.
        DISPLAY 
        EXIT PROGRAM.

* 添加到父视图
ADD-VIEW-TO-PARENT PROCEDURE.
    SET PAINT-ID IN VIEW TO PAINT-ID IN PARENT.
    IF PARENT-VIEWS IS NULL
        PERFORM INIT-PARENT-VIEWS
    END-IF
    ADD VIEW TO PARENT-VIEWS
    SET PARENT-ID IN VIEW TO PARENT-ID IN PARENT.
    EXIT PROGRAM.
    INIT-PARENT-VIEWS.
        DISPLAY 
        MOVE 0 TO VIEW-COUNT
    ADD VIEW TO PARENT-VIEWS.
        DISPLAY
        MOVE VIEW-RECORD TO TEMP-VIEW-RECORD
        ADD 1 TO VIEW-COUNT
        PERFORM INCREASE-ARRAY-SIZE
        MOVE TEMP-VIEW-RECORD TO PARENT-VIEWS (VIEW-COUNT)

* 清除视图
CLEAR-VIEWS PROCEDURE.
    DISPLAY 
    MOVE 0 TO VIEW-COUNT
    PERFORM RESET-ARRAY-SIZE
    EXIT PROGRAM.
    RESET-ARRAY-SIZE.
        DISPLAY 
        EXIT PROGRAM.

* 移除顶层视图
REMOVE-VIEW PROCEDURE.
    IF PAINT-VIEWS IS NOT NULL
        PERFORM VARYING I FROM 1 BY 1 UNTIL I > VIEW-COUNT
            IF PAINT-VIEWS (I).VIEW-ID = VIEW-ID IN VIEW
                PERFORM REMOVE-VIEW-FROM-ARRAY USING I
                MOVE "Y" TO RESULT-BOOLEAN
                EXIT PERFORM
            END-IF
        END-PERFORM
    END-IF
    EXIT PROGRAM.
    REMOVE-VIEW-FROM-ARRAY.
        DISPLAY 
        PERFORM VARYING J FROM I BY 1 UNTIL J > VIEW-COUNT
            MOVE PAINT-VIEWS (J + 1) TO PAINT-VIEWS (J)
        END-PERFORM
        SUBTRACT 1 FROM VIEW-COUNT
        PERFORM DECREASE-ARRAY-SIZE

    DECREASE-ARRAY-SIZE.
        DISPLAY 
        EXIT PROGRAM.

* 从父视图中移除
REMOVE-VIEW-FROM-PARENT PROCEDURE.
    IF PARENT-VIEWS IS NOT NULL
        PERFORM VARYING I FROM 1 BY 1 UNTIL I > VIEW-COUNT
            IF PARENT-VIEWS (I).VIEW-ID = VIEW-ID IN VIEW
                PERFORM REMOVE-VIEW-FROM-ARRAY USING I
                MOVE "Y" TO RESULT-BOOLEAN
                EXIT PERFORM
            END-IF
        END-PERFORM
    END-IF
    EXIT PROGRAM.

* 获取绝对位置X
CLIENT-X PROCEDURE.
    IF VIEW IS NOT NULL
        MOVE X IN LOCATION OF VIEW TO TEMP-X
        IF PARENT OF VIEW IS NOT NULL
            IF DISPLAY-OFFSET IN PARENT AND SCROLL-H IN PARENT > 0
                COMPUTE TEMP-X = TEMP-X + CLIENT-X (PARENT) - SCROLL-H IN PARENT
            ELSE
                COMPUTE TEMP-X = TEMP-X + CLIENT-X (PARENT)
            END-IF
        END-IF
    ELSE
        MOVE 0 TO TEMP-X
    END-IF
    EXIT PROGRAM.

* 获取绝对位置Y
CLIENT-Y PROCEDURE.
    IF VIEW IS NOT NULL
        MOVE Y IN LOCATION OF VIEW TO TEMP-Y
        IF PARENT OF VIEW IS NOT NULL
            IF DISPLAY-OFFSET IN PARENT AND SCROLL-V IN PARENT > 0
                COMPUTE TEMP-Y = TEMP-Y + CLIENT-Y (PARENT) - SCROLL-V IN PARENT
            ELSE
                COMPUTE TEMP-Y = TEMP-Y + CLIENT-Y (PARENT)
            END-IF
        END-IF
    ELSE
        MOVE 0 TO TEMP-Y
    END-IF
    EXIT PROGRAM.

* 是否包含坐标
CONTAINS-POINT PROCEDURE.
    IF IS-VIEW-ENABLED (VIEW) = "Y"
        PERFORM CLIENT-X USING VIEW RETURNING TEMP-X
        PERFORM CLIENT-Y USING VIEW RETURNING TEMP-Y
        MOVE CX IN SIZE OF VIEW TO TEMP-CX
        MOVE CY IN SIZE OF VIEW TO TEMP-CY
        COMPUTE TEMP-X = X IN MP - TEMP-X
        COMPUTE TEMP-Y = Y IN MP - TEMP-Y
        IF TEMP-X >= 0 AND TEMP-X <= TEMP-CX AND
           TEMP-Y >= 0 AND TEMP-Y <= TEMP-CY
            MOVE "Y" TO RESULT-BOOLEAN
        ELSE
            MOVE "N" TO RESULT-BOOLEAN
        END-IF
    ELSE
        MOVE "N" TO RESULT-BOOLEAN
    END-IF
    EXIT PROGRAM.

* 判断视图是否可用
IS-VIEW-ENABLED PROCEDURE.
    DISPLAY 
    EXIT PROGRAM.

* 查找有预处理事件的父视图
FIND-PREVIEWS-EVENT-PARENT PROCEDURE.
    IF NOT ALLOW-PREVIEWS-EVENT IN VIEW AND PARENT OF VIEW IS NOT NULL
        IF ALLOW-PREVIEWS-EVENT IN PARENT
            MOVE PARENT TO RESULT-VIEW
        ELSE
            PERFORM FIND-PREVIEWS-EVENT-PARENT USING PARENT RETURNING RESULT-VIEW
        END-IF
    ELSE
        MOVE NULL TO RESULT-VIEW
    END-IF
    EXIT PROGRAM.

* 根据名称查找视图
FIND-VIEW-BY-NAME PROCEDURE.
    MOVE SIZE OF VIEWS TO VIEW-COUNT
    PERFORM VARYING I FROM 1 BY 1 UNTIL I > VIEW-COUNT
        IF VIEW-NAME IN VIEWS (I) = NAME
            MOVE VIEWS (I) TO RESULT-VIEW
            EXIT PROGRAM
        ELSE
            IF VIEWS (I).VIEWS IS NOT NULL
                PERFORM FIND-VIEW-BY-NAME USING NAME VIEWS (I).VIEWS RETURNING RESULT-VIEW
                IF RESULT-VIEW IS NOT NULL
                    EXIT PROGRAM
                END-IF
            END-IF
        END-IF
    END-PERFORM
    MOVE NULL TO RESULT-VIEW
    EXIT PROGRAM.

IDENTIFICATION DIVISION.
PROGRAM-ID. ViewFunctionsInCobol.

DATA DIVISION.
WORKING-STORAGE SECTION.

01 VIEW-COUNT       PIC 9(3).
01 TEMP-VIEW-RECORD.
    05 TEMP-VIEW-ID  PIC 9(5).
    05 FILLER        PIC X(45).

01 TEMP-X           PIC S9(9)V9(2).
01 TEMP-Y           PIC S9(9)V9(2).


01 I                PIC 9(3).
01 J                PIC 9(3).

01 RESULT-BOOLEAN   PIC X(1).

PROCEDURE DIVISION.

FIND-VIEW PROCEDURE.
    MOVE SIZE OF VIEWS TO VIEW-COUNT
    PERFORM VARYING I FROM VIEW-COUNT BY -1 UNTIL I < 0
        MOVE VIEWS (I) TO TEMP-VIEW-RECORD
        IF VISIBLE IN TEMP-VIEW-RECORD AND TOP-MOST IN TEMP-VIEW-RECORD = "Y"
            PERFORM CONTAINS-POINT USING MP TEMP-VIEW-RECORD RETURNING RESULT-BOOLEAN
            IF RESULT-BOOLEAN = "Y"
                IF V-SCROLL-IS-VISIBLE IN TEMP-VIEW-RECORD AND SCROLL-SIZE IN TEMP-VIEW-RECORD > 0
                    PERFORM CLIENT-X USING TEMP-VIEW-RECORD RETURNING TEMP-X
                    IF X IN MP >= TEMP-X + CX IN SIZE OF TEMP-VIEW-RECORD - SCROLL-SIZE IN TEMP-VIEW-RECORD
                        MOVE TEMP-VIEW-RECORD TO RESULT-VIEW
                        EXIT PROGRAM
                    END-IF
                END-IF
                IF H-SCROLL-IS-VISIBLE IN TEMP-VIEW-RECORD AND SCROLL-SIZE IN TEMP-VIEW-RECORD > 0
                    PERFORM CLIENT-Y USING TEMP-VIEW-RECORD RETURNING TEMP-Y
                    IF Y IN MP >= TEMP-Y + CY IN SIZE OF TEMP-VIEW-RECORD - SCROLL-SIZE IN TEMP-VIEW-RECORD
                        MOVE TEMP-VIEW-RECORD TO RESULT-VIEW
                        EXIT PROGRAM
                    END-IF
                END-IF
                IF VIEWS (I).VIEWS IS NOT NULL
                    PERFORM FIND-VIEW USING MP VIEWS (I).VIEWS RETURNING RESULT-VIEW
                    IF RESULT-VIEW IS NOT NULL
                        EXIT PROGRAM
                    END-IF
                END-IF
                MOVE TEMP-VIEW-RECORD TO RESULT-VIEW
                EXIT PROGRAM
            END-IF
        END-IF
    END-PERFORM
    PERFORM VARYING I FROM VIEW-COUNT BY -1 UNTIL I < 0
        MOVE VIEWS (I) TO TEMP-VIEW-RECORD
        IF VISIBLE IN TEMP-VIEW-RECORD AND TOP-MOST IN TEMP-VIEW-RECORD = "N"
            PERFORM CONTAINS-POINT USING MP TEMP-VIEW-RECORD RETURNING RESULT-BOOLEAN
            IF RESULT-BOOLEAN = "Y"
                IF V-SCROLL-IS-VISIBLE IN TEMP-VIEW-RECORD AND SCROLL-SIZE IN TEMP-VIEW-RECORD > 0
                    PERFORM CLIENT-X USING TEMP-VIEW-RECORD RETURNING TEMP-X
                    IF X IN MP >= TEMP-X + CX IN SIZE OF TEMP-VIEW-RECORD - SCROLL-SIZE IN TEMP-VIEW-RECORD
                        MOVE TEMP-VIEW-RECORD TO RESULT-VIEW
                        EXIT PROGRAM
                    END-IF
                END-IF
                IF H-SCROLL-IS-VISIBLE IN TEMP-VIEW-RECORD AND SCROLL-SIZE IN TEMP-VIEW-RECORD > 0
                    PERFORM CLIENT-Y USING TEMP-VIEW-RECORD RETURNING TEMP-Y
                    IF Y IN MP >= TEMP-Y + CY IN SIZE OF TEMP-VIEW-RECORD - SCROLL-SIZE IN TEMP-VIEW-RECORD
                        MOVE TEMP-VIEW-RECORD TO RESULT-VIEW
                        EXIT PROGRAM
                    END-IF
                END-IF
                IF VIEWS (I).VIEWS IS NOT NULL
                    PERFORM FIND-VIEW USING MP VIEWS (I).VIEWS RETURNING RESULT-VIEW
                    IF RESULT-VIEW IS NOT NULL
                        EXIT PROGRAM
                    END-IF
                END-IF
                MOVE TEMP-VIEW-RECORD TO RESULT-VIEW
                EXIT PROGRAM
            END-IF
        END-IF
    END-PERFORM
    MOVE NULL TO RESULT-VIEW
    EXIT PROGRAM.

* 是否重绘时可见
IS-PAINT-VISIBLE PROCEDURE.
    IF VISIBLE IN VIEW = "Y"
        IF PARENT OF VIEW IS NOT NULL
            IF VISIBLE IN PARENT = "Y"
                PERFORM IS-PAINT-VISIBLE USING PARENT RETURNING RESULT-BOOLEAN
            ELSE
                MOVE "N" TO RESULT-BOOLEAN
            END-IF
        ELSE
            MOVE "Y" TO RESULT-BOOLEAN
        END-IF
    ELSE
        MOVE "N" TO RESULT-BOOLEAN
    END-IF
    EXIT PROGRAM.

* 是否视图可用
IS-VIEW-ENABLED PROCEDURE.
    IF ENABLED IN VIEW = "Y"
        IF PARENT OF VIEW IS NOT NULL
            IF ENABLED IN PARENT = "Y"
                PERFORM IS-VIEW-ENABLED USING PARENT RETURNING RESULT-BOOLEAN
            ELSE
                MOVE "N" TO RESULT-BOOLEAN
            END-IF
        ELSE
            MOVE "Y" TO RESULT-BOOLEAN
        END-IF
    ELSE
        MOVE "N" TO RESULT-BOOLEAN
    END-IF
    EXIT PROGRAM.

* 获取区域的交集
GET-INTERSECT-RECT PROCEDURE.
    MOVE MAX (LEFT IN LP-SRC1-RECT, LEFT IN LP-SRC2-RECT) TO LEFT IN LP-DEST-RECT
    MOVE MIN (RIGHT IN LP-SRC1-RECT, RIGHT IN LP-SRC2-RECT) TO RIGHT IN LP-DEST-RECT
    MOVE MAX (TOP IN LP-SRC1-RECT, TOP IN LP-SRC2-RECT) TO TOP IN LP-DEST-RECT
    MOVE MIN (BOTTOM IN LP-SRC1-RECT, BOTTOM IN LP-SRC2-RECT) TO BOTTOM IN LP-DEST-RECT
    IF RIGHT IN LP-DEST-RECT > LEFT IN LP-DEST-RECT AND BOTTOM IN LP-DEST-RECT > TOP IN LP-DEST-RECT
        MOVE 1 TO RETURN-CODE
    ELSE
        MOVE 0 TO LEFT IN LP-DEST-RECT
        MOVE 0 TO RIGHT IN LP-DEST-RECT
        MOVE 0 TO TOP IN LP-DEST-RECT
        MOVE 0 TO BOTTOM IN LP-DEST-RECT
        MOVE 0 TO RETURN-CODE
    END-IF
    EXIT PROGRAM.

* 重绘视图
RENDER-VIEWS PROCEDURE.
    MOVE SIZE OF VIEWS TO VIEW-COUNT
    PERFORM VARYING I FROM 1 BY 1 UNTIL I > VIEW-COUNT
        MOVE VIEWS (I) TO TEMP-VIEW-RECORD
        IF RECT IS NULL
            IF VIEWS (I).VIEWS IS NOT NULL
                MOVE SIZE OF VIEWS (I).VIEWS TO SUB-VIEWS-SIZE
                IF SUB-VIEWS-SIZE > 0
                    PERFORM RENDER-VIEWS USING VIEWS (I).VIEWS PAINT NULL
                END-IF
            END-IF
            SET CLIP-RECT IN TEMP-VIEW-RECORD TO NULL
            NEXT SENTENCE
        END-IF
        IF TOP-MOST IN TEMP-VIEW-RECORD = "N" AND IS-PAINT-VISIBLE (TEMP-VIEW-RECORD) = "Y"
            PERFORM CLIENT-X USING TEMP-VIEW-RECORD RETURNING TEMP-X
            PERFORM CLIENT-Y USING TEMP-VIEW-RECORD RETURNING TEMP-Y
            MOVE 0 TO LEFT IN DRAW-RECT
            MOVE 0 TO TOP IN DRAW-RECT
            MOVE CX IN SIZE OF TEMP-VIEW-RECORD TO RIGHT IN DRAW-RECT
            MOVE CY IN SIZE OF TEMP-VIEW-RECORD TO BOTTOM IN DRAW-RECT
            MOVE TEMP-X TO LEFT IN CLIP-RECT
            MOVE TEMP-Y TO TOP IN CLIP-RECT
            COMPUTE RIGHT IN CLIP-RECT = TEMP-X + CX IN SIZE OF TEMP-VIEW-RECORD
            COMPUTE BOTTOM IN CLIP-RECT = TEMP-Y + CY IN SIZE OF TEMP-VIEW-RECORD
            MOVE 0 TO LEFT IN DEST-RECT
            MOVE 0 TO TOP IN DEST-RECT
            MOVE 0 TO RIGHT IN DEST-RECT
            MOVE 0 TO BOTTOM IN DEST-RECT
            PERFORM GET-INTERSECT-RECT USING DEST-RECT CLIP-RECT RECT RETURNING RETURN-CODE
            IF RETURN-CODE > 0
                PERFORM PAINT-SAVE USING PAINT
                PERFORM PAINT-SET-OFFSET USING PAINT 0 0
                PERFORM PAINT-SET-CLIP USING PAINT LEFT IN DEST-RECT TOP IN DEST-RECT RIGHT IN DEST-RECT BOTTOM IN DEST-RECT
                SET CLIP-RECT IN TEMP-VIEW-RECORD TO DEST-RECT
                PERFORM PAINT-SET-OFFSET USING PAINT TEMP-X TEMP-Y
                IF VIEWS (I).VIEWS IS NOT NULL
                    MOVE SIZE OF VIEWS (I).VIEWS TO SUB-VIEWS-SIZE
                    IF SUB-VIEWS-SIZE > 0
                        PERFORM RENDER-VIEWS USING VIEWS (I).VIEWS PAINT DEST-RECT
                    END-IF
                END-IF
                PERFORM PAINT-SET-OFFSET USING PAINT TEMP-X TEMP-Y
                PERFORM PAINT-RESTORE USING PAINT
            ELSE
                IF VIEWS (I).VIEWS IS NOT NULL
                    MOVE SIZE OF VIEWS (I).VIEWS TO SUB-VIEWS-SIZE
                    IF SUB-VIEWS-SIZE > 0
                        PERFORM RENDER-VIEWS USING VIEWS (I).VIEWS PAINT NULL
                    END-IF
                END-IF
                SET CLIP-RECT IN TEMP-VIEW-RECORD TO NULL
            END-IF
        END-IF
    END-PERFORM
    PERFORM VARYING I FROM 1 BY 1 UNTIL I > VIEW-COUNT
        MOVE VIEWS (I) TO TEMP-VIEW-RECORD
        IF RECT IS NULL
            NEXT SENTENCE
        END-IF
        IF TOP-MOST IN TEMP-VIEW-RECORD = "Y" AND IS-PAINT-VISIBLE (TEMP-VIEW-RECORD) = "Y"
            PERFORM CLIENT-X USING TEMP-VIEW-RECORD RETURNING TEMP-X
            PERFORM CLIENT-Y USING TEMP-VIEW-RECORD RETURNING TEMP-Y
            MOVE 0 TO LEFT IN DRAW-RECT
            MOVE 0 TO TOP IN DRAW-RECT
            MOVE CX IN SIZE OF TEMP-VIEW-RECORD TO RIGHT IN DRAW-RECT
            MOVE CY IN SIZE OF TEMP-VIEW-RECORD TO BOTTOM IN DRAW-RECT
            MOVE TEMP-X TO LEFT IN CLIP-RECT
            MOVE TEMP-Y TO TOP IN CLIP-RECT
            COMPUTE RIGHT IN CLIP-RECT = TEMP-X + CX IN SIZE OF TEMP-VIEW-RECORD
            COMPUTE BOTTOM IN CLIP-RECT = TEMP-Y + CY IN SIZE OF TEMP-VIEW-RECORD
            MOVE 0 TO LEFT IN DEST-RECT
            MOVE 0 TO TOP IN DEST-RECT
            MOVE 0 TO RIGHT IN DEST-RECT
            MOVE 0 TO BOTTOM IN DEST-RECT
            PERFORM GET-INTERSECT-RECT USING DEST-RECT CLIP-RECT RECT RETURNING RETURN-CODE
            IF RETURN-CODE > 0
                PERFORM PAINT-SAVE USING PAINT
                PERFORM PAINT-SET-OFFSET USING PAINT 0 0
                SET CLIP-RECT IN TEMP-VIEW-RECORD TO DEST-RECT
                PERFORM PAINT-SET-CLIP USING PAINT LEFT IN DEST-RECT TOP IN DEST-RECT RIGHT IN DEST-RECT BOTTOM IN DEST-RECT
                PERFORM PAINT-SET-OFFSET USING PAINT TEMP-X TEMP-Y
                IF VIEWS (I).VIEWS IS NOT NULL
                    MOVE SIZE OF VIEWS (I).VIEWS TO SUB-VIEWS-SIZE
                    IF SUB-VIEWS-SIZE > 0
                        PERFORM RENDER-VIEWS USING VIEWS (I).VIEWS PAINT DEST-RECT
                    END-IF
                END-IF
                PERFORM PAINT-SET-OFFSET USING PAINT TEMP-X TEMP-Y
                PERFORM PAINT-RESTORE USING PAINT
            ELSE
                IF VIEWS (I).VIEWS IS NOT NULL
                    MOVE SIZE OF VIEWS (I).VIEWS TO SUB-VIEWS-SIZE
                    IF SUB-VIEWS-SIZE > 0
                        PERFORM RENDER-VIEWS USING VIEWS (I).VIEWS PAINT NULL
                    END-IF
                END-IF
                SET CLIP-RECT IN TEMP-VIEW-RECORD TO NULL
            END-IF
        END-IF
    END-PERFORM
    EXIT PROGRAM.

* 全局刷新
INVALIDATE PROCEDURE.
    DISPLAY 
    EXIT PROGRAM.

* 刷新视图
INVALIDATE-VIEW PROCEDURE.
    DISPLAY 
    EXIT PROGRAM.